import {
  OnInit,
  Component,
  ViewChild,
  TemplateRef,
  Input,
  Output,
  EventEmitter,
  OnDestroy,
  OnChanges,
} from '@angular/core'
import { DetailHeaderComponent } from '../detail-header/detail-header.component'
import { Observable, of, Subject } from 'rxjs'
import { IDetailHeaderTab, Country } from '@shared/interfaces/common'
import { DetailBaseClass } from '@shared/classes/DetailBaseClass'
import { PostRiskScheme } from '@shared/interfaces/post-risk-control'
import { EOtherDetailTab } from '@shared/interfaces/store'
import { ActivatedRoute } from '@angular/router'
import { NzMessageService } from 'ng-zorro-antd'
import { TitleService } from '@delon/theme'
import { PageService } from '@shared/services/page.service'
import { ACLService } from '@delon/acl'
import { AcquirerService } from 'app/routes/acquirer/acquirer.service'
import { AcquirerAlinterService } from 'app/routes/acquirer/acquirer-alinter.service'
import { getObjectValue } from 'app/utils/helpers'
import { ETabScrollStatus } from '@shared/enums'
import { StoreAlinterService } from 'app/routes/store/store-alinter.service'
import { StoreService } from 'app/routes/store/store.service'
import { DataService } from '@shared/services/data.service'
import { I18NService } from '@core'
import { SchemeStatusTextMap } from '@shared/interfaces/common'

@Component({
  selector: 'app-postrisk-detail',
  templateUrl: './postrisk-detail.component.html',
  providers: [
    { provide: AcquirerService, useClass: AcquirerAlinterService },
    { provide: StoreService, useClass: StoreAlinterService },
  ],
})
export class PostriskDetailComponent extends DetailBaseClass<PostRiskScheme> implements OnInit, OnDestroy, OnChanges {
  SchemeStatusTextMap = SchemeStatusTextMap
  @Input() isNeedDiff = false // 是否需要使用diff
  @Input() data: PostRiskScheme
  @Input() origData: PostRiskScheme
  @Input() data$: Observable<PostRiskScheme>
  @Input() isEditable = true
  @Input() token: string
  @Output() downloadEvent: Subject<void> = new Subject()
  @Output() cancelEvent = new EventEmitter()
  @ViewChild('tplCurrency') tplCurrency: TemplateRef<any>
  @ViewChild(DetailHeaderComponent) detailHeaderComponent: DetailHeaderComponent
  tabs$: Observable<IDetailHeaderTab[]>
  tabs: IDetailHeaderTab[] = [
    { key: EOtherDetailTab.Rules, text: this.trans('RISK_CTRL.RULES'), url: './rules' },
    { key: EOtherDetailTab.Range, text: this.trans('GENERAL.INFO.RANGE'), url: './range' },
    { key: EOtherDetailTab.Merchant, text: this.trans('AUDIT.TYPE.STORE'), url: './merchant' },
  ]
  isCurrencyMultiple = false

  constructor(
    public route: ActivatedRoute,
    public msg: NzMessageService,
    public titleService: TitleService,
    public pageService: PageService,
    public aclService: ACLService,
    private dataService: DataService,
    private i18n: I18NService,
  ) {
    super(pageService)
  }

  ngOnInit() {
    this.setData()

    this.initialColumns()
    this.initColumns()
    this.parseTabsWithDiffCheck(this.tabs)
  }

  ngOnChanges() {
    this.detailData = this.data
    this.initialColumns()
    this.initColumns()
  }

  ngOnDestroy() {
    this.resetData()
    this.pageService.triggerBaseEdit(false)
    this.pageService.setTabScrollStatus(ETabScrollStatus.InitialLoad)
  }

  parseTabsWithDiffCheck(tabs: IDetailHeaderTab[]): IDetailHeaderTab[] {
    if (!this.isNeedDiff) {
      return this.tabs
    }
    this.tabs = this.removeTab(tabs, EOtherDetailTab.Merchant)
    this.tabs = this.removeTab(tabs, EOtherDetailTab.Range)
    return this.tabs
  }

  removeTab(tabs: IDetailHeaderTab[], key: string): IDetailHeaderTab[] {
    return tabs.filter(tab => tab.key !== key)
  }

  /** 判断新旧两个值是否不同，如果diff，则返回 true */
  checkDiff(index: string): boolean {
    /** 如果不需要Diff，直接返回false */
    if (!this.isNeedDiff) return false
    const origValue = getObjectValue(index, this.origData)
    const currentValue = getObjectValue(index, this.data)
    return origValue !== currentValue
  }

  initialColumns() {
    this.firstColumns = [
      {
        span: 7,
        index: 'schemeCode',
        label: 'RISK_CTRL.SCHEME_CODE',
        labelI18n: 'RISK_CTRL.SCHEME_CODE',
      },
      {
        span: 8,
        index: 'schemeName',
        label: 'RISK_CTRL.SCHEME_NAME',
        labelI18n: 'RISK_CTRL.SCHEME_NAME',
      },
      {
        span: 7,
        index: 'insCode',
        label: 'ROLE.OWNER_INSTITUTION',
        labelI18n: 'ROLE.OWNER_INSTITUTION',
        disEditable: true,
      },
    ]

    this.secondColumns = [
      {
        span: 7,
        index: 'schemeDesc',
        label: 'RISK_CTRL.SCHEME_DESC',
        labelI18n: 'RISK_CTRL.SCHEME_DESC',
      },
      {
        span: 8,
        index: 'currency',
        label: 'GENERAL.INFO.CURRENCY',
        labelI18n: 'GENERAL.INFO.CURRENCY',
      },
      {
        span: 7,
        index: 'status',
        label: 'GENERAL.INFO.STATUS',
        labelI18n: 'GENERAL.INFO.STATUS',
        displayValue: this.getSchemeStatus(this.detailData.status),
      },
    ]
  }

  transCountriesToOptions(countries: Country[]) {
    return countries.map(country => {
      return { label: country.name, value: country.codeAlpha3 }
    })
  }

  download(): void {
    this.downloadEvent.next()
  }

  triggerBaseEdit(): void {
    this.copiedDetailData = this.copyDetailData(this.detailData)
    this.pageService.triggerBaseEdit(true)
  }

  private setData(): void {
    this.detailData = this.data
    if (!this.data) {
      this.detailData = this.origData
    }
    if (this.data) {
      this.dataService.setCurrentPostrisk(this.data)
    }
    if (this.origData) {
      this.dataService.setOrigPostrisk(this.origData)
    }
    this.trans(this.detailData ? SchemeStatusTextMap[this.detailData.status] : '')
    this.dataService.setIsNeedDiff(this.isNeedDiff)
  }

  private resetData(): void {
    this.dataService.resetOrigStore()
    this.dataService.resetCurrentStore()
    this.dataService.resetIsNeedDiff()
  }

  getSchemeStatus(status: string): string {
    try {
      return this.trans(SchemeStatusTextMap[status])
    } catch (e) {
      return this.trans('GENERAL.INFO.NONE')
    }
  }

  private trans(key?: string, params?: Object): string {
    return this.i18n.fanyi(key, params)
  }
}
